/*
    This file is part of QTau
    Copyright (C) 2013-2018  Tobias "Tomoko" Platen <tplaten@posteo.de>
    Copyright (C) 2013       digited       <https://github.com/digited>
    Copyright (C) 2010-2013  HAL@ShurabaP  <https://github.com/haruneko>

    QTau is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    SPDX-License-Identifier: GPL-3.0+
*/

#ifndef JACKCONNECTOR_H
#define JACKCONNECTOR_H

#include <jack/jack.h>
#include <jack/ringbuffer.h>
#include "Utils.h"

typedef jack_default_audio_sample_t sample_t;

#define TRANSPORT_NONE 0
#define TRANSPORT_START 1
#define TRANSPORT_STOP 2
#define TRANSPORT_ZERO 3
#define TRANSPORT_STARTPOS 4

class JackAudio
{
    jack_client_t* _client=nullptr;
    jack_port_t* _write_port=nullptr;
    jack_ringbuffer_t* _write_rb=nullptr;
    jack_ringbuffer_t* _control_rb=nullptr;
    jack_port_t* _midi_port=nullptr;
    jack_ringbuffer_t* _midi_rb=nullptr;
    bool _playback=false;
    jack_transport_state_t _transport_state;
    jack_transport_state_t _previous_transport_state;
    volatile int _transport_command=0;
    int _buffer_size=0;
    bool _use_transport=0;
    bool _state_changed=0;
    int _position=0;
    int _eventfd=0;
    float _startpos=0;
    static int process (jack_nframes_t nframes, void *arg);
    static int sync(jack_transport_state_t state, jack_position_t *pos, void *arg);
public:
    explicit JackAudio(bool autoconnect);
    void shutdown();
    int sampleRate();
    int writeData(void* famebuf,int bytes_per_frame);
    void changeTranportState(int command){_transport_command = command;}
    bool isRolling() {return _transport_state==JackTransportRolling;}
    void setUseTransport(bool use_transport){_use_transport=use_transport;}
    int getBufferSize() {return _buffer_size;}
    float* allocateBuffer();
    bool stateChanged(){bool retval= _state_changed;_state_changed=false;return retval;}
    int positionChange(){int retval= _position; _position=-1;return retval;}
    jack_transport_state_t transportState(){return _transport_state;}
    int createEFD();
    int getSamplerate(){return jack_get_sample_rate(_client);}
    int readMidiData(char* buffer,int maxlength);
    void transportStartPos(float startpos){_startpos=startpos;_transport_command=TRANSPORT_STARTPOS;}


    
};

#endif // JACKCONNECTOR_H

